package com.obas.access.business.service.impl;

import java.util.List;

import com.ease.common.vo.MapParameter;
import com.ease.platform.access.service.impl.AbstractNamespaceAccessServiceImpl;
import com.obas.access.business.service.BusinessFunctionAccessService;
import com.obas.access.business.service.SystemFunctionAccessService;
import com.obas.access.business.service.SystemUsecaseAccessService;
import com.obas.model.business.BusinessFunction;
import com.obas.model.business.BusinessUsecase;
import com.obas.model.business.SystemFunction;
import com.obas.model.business.SystemUsecase;
import com.obas.model.business.criteria.SystemUsecaseCriteria;

public class SystemUsecaseAccessServiceImpl extends AbstractNamespaceAccessServiceImpl<SystemUsecase> implements SystemUsecaseAccessService {

	static final class Statement {

		public static final String associateSystemScenario = "associateSystemScenario";
		public static final String disassociateSystemScenario = "disassociateSystemScenario";
		public static final String disassociateAllSystemScenario = "disassociateAllSystemScenario";
		public static final String disassociateAllSystemFunction = "disassociateAllSystemFunction";
	}

	private BusinessFunctionAccessService businessFunctionAccessService;

	private SystemFunctionAccessService systemFunctionAccessService;

	public List<SystemUsecase> findBySystemScenarioId(long systemScenarioId) {
		SystemUsecaseCriteria parameter = new SystemUsecaseCriteria();
		parameter.setSystemScenarioId(systemScenarioId);
		return this.find(parameter);
	}

	public SystemUsecase createEntity(SystemUsecase systemUsecase, long systemScenarioId) {
		systemUsecase = this.create(systemUsecase);
		if (systemScenarioId > 0) {
			associateSystemScenario(systemUsecase.getId(), systemScenarioId);
		}
		return systemUsecase;
	}

	public SystemUsecase createEntityWithBusinessUsecase(SystemUsecase systemUsecase, long systemScenarioId, BusinessUsecase businessUsecase) {

		systemUsecase = this.createEntity(systemUsecase, systemScenarioId);

		List<BusinessFunction> businessFunctions = businessFunctionAccessService.findByBusinessUsecaseId(businessUsecase.getId());

		for (int i = 0; i < businessFunctions.size(); i++) {
			BusinessFunction businessFunction = businessFunctions.get(i);
			SystemFunction systemFunction = new SystemFunction();
			systemFunction.setName(businessFunction.getName());
			systemFunction = systemFunctionAccessService.createEntity(systemFunction, systemUsecase.getId());
		}

		return systemUsecase;
	}

	public SystemUsecase remove(SystemUsecase systemUsecase) {
		if (null != systemUsecase) {

			long systemUsecaseId = systemUsecase.getId();
			//
			disassociateAll(systemUsecaseId, systemUsecase);
			//
			systemUsecase = super.remove(systemUsecase);
			//
			removeCascade(systemUsecaseId, systemUsecase);
		}
		return systemUsecase;
	}

	public void removeCascade(long systemUsecaseId, SystemUsecase systemUsecase) {
		{/* TBD */
			List<SystemFunction> systemFunctions = systemFunctionAccessService.findBySystemUsecaseId(systemUsecaseId);
			if (notEmpty(systemFunctions)) {
				for (SystemFunction systemFunction : systemFunctions) {
					systemFunctionAccessService.remove(systemFunction);
				}
			}
		}
	}

	public void disassociateAll(long systemUsecaseId, SystemUsecase systemUsecase) {
		disassociateAllSystemScenario(systemUsecaseId);
		disassociateAllSystemFunction(systemUsecaseId);
	}

	public void disassociateAllSystemScenario(long systemUsecaseId) {
		MapParameter parameter = new MapParameter();
		parameter.put("systemUsecaseId", systemUsecaseId);
		this.update(Statement.disassociateAllSystemScenario, parameter);
	}

	public void disassociateAllSystemFunction(long systemUsecaseId) {
		MapParameter parameter = new MapParameter();
		parameter.put("systemUsecaseId", systemUsecaseId);
		this.update(Statement.disassociateAllSystemFunction, parameter);
	}

	public void associateSystemScenario(long systemUsecaseId, long systemScenarioId) {
		MapParameter parameter = new MapParameter();
		parameter.put("systemScenarioId", systemScenarioId);
		parameter.put("systemUsecaseId", systemUsecaseId);
		this.update(Statement.associateSystemScenario, parameter);
	}

	public void disassociateSystemScenario(long systemUsecaseId, long systemScenarioId) {
		MapParameter parameter = new MapParameter();
		parameter.put("systemScenarioId", systemScenarioId);
		parameter.put("systemUsecaseId", systemUsecaseId);
		this.remove(Statement.disassociateSystemScenario, parameter);
	}

	/**
	 * @return the businessFunctionAccessService
	 */
	public BusinessFunctionAccessService getBusinessFunctionAccessService() {
		return businessFunctionAccessService;
	}

	/**
	 * @param businessFunctionAccessService
	 *            the businessFunctionAccessService to set
	 */
	public void setBusinessFunctionAccessService(BusinessFunctionAccessService businessFunctionAccessService) {
		this.businessFunctionAccessService = businessFunctionAccessService;
	}

	/**
	 * @return the systemFunctionAccessService
	 */
	public SystemFunctionAccessService getSystemFunctionAccessService() {
		return systemFunctionAccessService;
	}

	/**
	 * @param systemFunctionAccessService
	 *            the systemFunctionAccessService to set
	 */
	public void setSystemFunctionAccessService(SystemFunctionAccessService systemFunctionAccessService) {
		this.systemFunctionAccessService = systemFunctionAccessService;
	}

}
